#include "InputLayer.h"
#include "InputField.h"
#include "Road.h"
#include "GameManager.h"

#define NUM_ROW 7
#define X_FIRST_COLUMN 170
#define COLUMN_DISTANCE 350
#define FONT_SIZE 20

InputLayer::InputLayer():CCLayer(){

}

InputLayer::~InputLayer(){

}

bool InputLayer::init(){
	CCLayer::init();

	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
	GameManager* gameManager = GameManager::getInstance();

	float inputWidth = 300;
	float inputHeight = 40;
	float labelWidth = 200;

	int index = 0;
	CCPoint inputLocation;

	char cValue[8] = {0};

	roadLengthInput = new InputField();
	inputLocation = getInputPosition(index);
	roadLengthInput->init(CCRectMake(inputLocation.x, inputLocation.y, inputWidth, inputHeight), "Road length (m)", FONT_SIZE, labelWidth);
	sprintf(cValue, "%.2f", gameManager->roadLength/METTER_TO_POINT);
	roadLengthInput->editBox->setText(cValue);
	addChild(roadLengthInput);
	index++;

	roadLaneWidthInput = new InputField();
	inputLocation = getInputPosition(index);
	roadLaneWidthInput->init(CCRectMake(inputLocation.x, inputLocation.y, inputWidth, inputHeight), "Road width (m)", FONT_SIZE, labelWidth);
	sprintf(cValue, "%.2f", gameManager->laneWidth/METTER_TO_POINT);
	roadLaneWidthInput->editBox->setText(cValue);
	addChild(roadLaneWidthInput);
	index++;

	motoWidthInput = new InputField();
	inputLocation = getInputPosition(index);
	motoWidthInput->init(CCRectMake(inputLocation.x, inputLocation.y, inputWidth, inputHeight), "Motorbike width (m)", FONT_SIZE, labelWidth);
	sprintf(cValue, "%.2f", gameManager->motoWidth/METTER_TO_POINT);
	motoWidthInput->editBox->setText(cValue);
	addChild(motoWidthInput);
	index++;

	motoLengthInput = new InputField();
	inputLocation = getInputPosition(index);
	motoLengthInput->init(CCRectMake(inputLocation.x, inputLocation.y, inputWidth, inputHeight), "Motorbike length (m)", FONT_SIZE, labelWidth);
	sprintf(cValue, "%.2f", gameManager->motoLength/METTER_TO_POINT);
	motoLengthInput->editBox->setText(cValue);
	addChild(motoLengthInput);
	index++;

	carWidthInput = new InputField();
	inputLocation = getInputPosition(index);
	carWidthInput->init(CCRectMake(inputLocation.x, inputLocation.y, inputWidth, inputHeight), "Car width (m)", FONT_SIZE, labelWidth);
	sprintf(cValue, "%.2f", gameManager->carWidth/METTER_TO_POINT);
	carWidthInput->editBox->setText(cValue);
	addChild(carWidthInput);
	index++;

	carLengthInput = new InputField();
	inputLocation = getInputPosition(index);
	carLengthInput->init(CCRectMake(inputLocation.x, inputLocation.y, inputWidth, inputHeight), "Car length (m)", FONT_SIZE, labelWidth);
	sprintf(cValue, "%.2f", gameManager->carLength/METTER_TO_POINT);
	carLengthInput->editBox->setText(cValue);
	addChild(carLengthInput);
	index++;

	busWidthInput = new InputField();
	inputLocation = getInputPosition(index);
	busWidthInput->init(CCRectMake(inputLocation.x, inputLocation.y, inputWidth, inputHeight), "Bus width (m)", FONT_SIZE, labelWidth);
	sprintf(cValue, "%.2f", gameManager->busWidth/METTER_TO_POINT);
	busWidthInput->editBox->setText(cValue);
	addChild(busWidthInput);
	index++;

	busLengthInput = new InputField();
	inputLocation = getInputPosition(index);
	busLengthInput->init(CCRectMake(inputLocation.x, inputLocation.y, inputWidth, inputHeight), "Bus length (m)", FONT_SIZE, labelWidth);
	sprintf(cValue, "%.2f", gameManager->busLength/METTER_TO_POINT);
	busLengthInput->editBox->setText(cValue);
	addChild(busLengthInput);
	index++;

	greenLightTimeInput = new InputField();
	inputLocation = getInputPosition(index);
	greenLightTimeInput->init(CCRectMake(inputLocation.x, inputLocation.y, inputWidth, inputHeight), "Green traffic light time (s)", FONT_SIZE, labelWidth);
	sprintf(cValue, "%.2f", gameManager->greenLightTime);
	greenLightTimeInput->editBox->setText(cValue);
	addChild(greenLightTimeInput);
	index++;

	redLightTimeInput = new InputField();
	inputLocation = getInputPosition(index);
	redLightTimeInput->init(CCRectMake(inputLocation.x, inputLocation.y, inputWidth, inputHeight), "Red traffic light time (s)", FONT_SIZE, labelWidth);
	sprintf(cValue, "%.2f", gameManager->redLightTime);
	redLightTimeInput->editBox->setText(cValue);
	addChild(redLightTimeInput);
	index++;

	vMaxMotoInput = new InputField();
	inputLocation = getInputPosition(index);
	vMaxMotoInput->init(CCRectMake(inputLocation.x, inputLocation.y, inputWidth, inputHeight), "Motorbike V-max (m/s)", FONT_SIZE, labelWidth);
	sprintf(cValue, "%.2f", gameManager->vMotoMax/METTER_TO_POINT);
	vMaxMotoInput->editBox->setText(cValue);
	addChild(vMaxMotoInput);
	index++;

	vMaxCarInput = new InputField();
	inputLocation = getInputPosition(index);
	vMaxCarInput->init(CCRectMake(inputLocation.x, inputLocation.y, inputWidth, inputHeight), "Car V-max (m/s)", FONT_SIZE, labelWidth);
	sprintf(cValue, "%.2f", gameManager->vCarMax/METTER_TO_POINT);
	vMaxCarInput->editBox->setText(cValue);
	addChild(vMaxCarInput);
	index++;

	vMaxBusInput = new InputField();
	inputLocation = getInputPosition(index);
	vMaxBusInput->init(CCRectMake(inputLocation.x, inputLocation.y, inputWidth, inputHeight), "Bus V-max (m/s)", FONT_SIZE, labelWidth);
	sprintf(cValue, "%.2f", gameManager->vBusMax/METTER_TO_POINT);
	vMaxBusInput->editBox->setText(cValue);
	addChild(vMaxBusInput);
	index++;

	// choose bus lane mode
	
	// label
	CCLabelTTF* chooseBusLaneModeLabel = CCLabelTTF::create("Choose bus lane mode:", "", 20);
	chooseBusLaneModeLabel->setPosition(ccp(X_FIRST_COLUMN + 2*COLUMN_DISTANCE, visibleSize.height - 60));
	addChild(chooseBusLaneModeLabel);

	// menu
	CCNode* chooseBusLaneModeNode = CCNode::create();
	chooseBusLaneModeNode->setPosition(chooseBusLaneModeLabel->getPositionX() - 30, chooseBusLaneModeLabel->getPositionY() - 80);
	addChild(chooseBusLaneModeNode);

	CCMenuItemLabel* onlyBusMenuItem = CCMenuItemLabel::create(CCLabelTTF::create("Bus", "", 15, CCSizeMake(150, 30), kCCTextAlignmentLeft, kCCVerticalTextAlignmentCenter), this, menu_selector(InputLayer::onlyBusMenuTouched));
	CCMenuItemLabel* busMotoMenuItem = CCMenuItemLabel::create(CCLabelTTF::create("Bus, motorbike", "", 15, CCSizeMake(150, 30), kCCTextAlignmentLeft, kCCVerticalTextAlignmentCenter), this, menu_selector(InputLayer::busMotoMenuTouched));
	CCMenuItemLabel* allVerhicleMenuItem = CCMenuItemLabel::create(CCLabelTTF::create("All", "", 15, CCSizeMake(150, 30), kCCTextAlignmentLeft, kCCVerticalTextAlignmentCenter), this, menu_selector(InputLayer::allVerhicleMenuTouched));
	menu = CCMenu::create(onlyBusMenuItem, busMotoMenuItem, allVerhicleMenuItem, 0);
	menu->alignItemsVerticallyWithPadding(10);
	menu->setPosition(20, 0);
	chooseBusLaneModeNode->addChild(menu);

	// indicator
	busLaneModeIndicatorSprite = CCSprite::createWithSpriteFrameName("Moto.png");
	busLaneModeIndicatorSprite->setScale(0.5);
	chooseBusLaneModeNode->addChild(busLaneModeIndicatorSprite);
	chooseLaneMode(gameManager->busLaneMode);

	// ok, cancel button
	int centerPadding = 40;
	int yButton = 60;
	CCControlButton* okButton = CCControlButton::create();
	okButton->setBackgroundSpriteFrameForState(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("OkIcon.png"), CCControlStateNormal);
	okButton->setAdjustBackgroundImage(false);
	okButton->setPosition(ccp(X_FIRST_COLUMN + 2*COLUMN_DISTANCE - centerPadding, yButton));
	okButton->addTargetWithActionForControlEvents(this, cccontrol_selector(InputLayer::okButtonTouched), CCControlEventTouchUpInside);
	addChild(okButton);

	CCControlButton* cancelButton = CCControlButton::create();
	cancelButton->setBackgroundSpriteFrameForState(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("CancelIcon.png"), CCControlStateNormal);
	cancelButton->setAdjustBackgroundImage(false);
	cancelButton->setPosition(ccp(X_FIRST_COLUMN + 2*COLUMN_DISTANCE + centerPadding, yButton));
	cancelButton->addTargetWithActionForControlEvents(this, cccontrol_selector(InputLayer::cancelButtonTouched), CCControlEventTouchUpInside);
	addChild(cancelButton);

	return true;
}

CCPoint InputLayer::getInputPosition(int index){
	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
	float rowDistance = visibleSize.height/(NUM_ROW + 1);

	float x = X_FIRST_COLUMN + (index/NUM_ROW)*COLUMN_DISTANCE;
	float y = visibleSize.height - (index%NUM_ROW + 1)*rowDistance;
	return ccp(x, y);
}

void InputLayer::onlyBusMenuTouched(CCObject* sender){
	chooseLaneMode(BLM_BUS);
}

void InputLayer::busMotoMenuTouched(CCObject* sender){
	chooseLaneMode(BLM_BUS_MOTOR);
}
void InputLayer::allVerhicleMenuTouched(CCObject* sender){
	chooseLaneMode(BLM_ALL);
}

void InputLayer::chooseLaneMode(int busLaneModeSelected){
	float indicatorX = menu->getPositionX() - 90;
	this->busLaneModeSelected = busLaneModeSelected;
	int menuItemVerPadding = 40;

	switch (busLaneModeSelected)
	{
	case BLM_BUS:
		busLaneModeIndicatorSprite->setPosition(ccp(indicatorX, menu->getPositionY() + menuItemVerPadding));
		break;

	case BLM_BUS_MOTOR:
		busLaneModeIndicatorSprite->setPosition(ccp(indicatorX, menu->getPositionY()));
		break;

	case BLM_ALL:
		busLaneModeIndicatorSprite->setPosition(ccp(indicatorX, menu->getPositionY() - menuItemVerPadding));
		break;
	}
}

void InputLayer::okButtonTouched(CCObject* sender, CCControlEvent event){
	
	GameManager* gameManager = GameManager::getInstance();

	char* textBoxString;
	char errorMessage[512] = {'\0'};
	char errorMessageTemp[64] = {'\0'};
	bool isAllInputValid = true;

	float roadLength = 0;
	textBoxString = (char*)roadLengthInput->editBox->getText();
	roadLength = atof(textBoxString);
	if(roadLength < MIN_ROAD_LENGTH || roadLength > MAX_ROAD_LENGTH){
		isAllInputValid = false;
		sprintf(errorMessageTemp, "* %f < road length < %f\n", MIN_ROAD_LENGTH, MAX_ROAD_LENGTH);
		strcat(errorMessage, errorMessageTemp);
	}

	float laneWidth = 0;
	textBoxString = (char*)roadLaneWidthInput->editBox->getText();
	laneWidth = atof(textBoxString);
	if(laneWidth < MIN_LANE_WIDTH || laneWidth > MAX_LANE_WIDTH){
		isAllInputValid = false;
		sprintf(errorMessageTemp, "* %f < lane width < %f\n", MIN_LANE_WIDTH, MAX_LANE_WIDTH);
		strcat(errorMessage, errorMessageTemp);
	}
	
	float motoWidth = 0;
	textBoxString = (char*)motoWidthInput->editBox->getText();
	motoWidth = atof(textBoxString);
	if(motoWidth < MIN_MOTO_WIDTH || motoWidth > MAX_MOTO_WIDTH){
		isAllInputValid = false;
		sprintf(errorMessageTemp, "* %f < moto width < %f\n", MIN_MOTO_WIDTH, MAX_MOTO_WIDTH);
		strcat(errorMessage, errorMessageTemp);
	}

	float motoLength = 0;
	textBoxString = (char*)motoLengthInput->editBox->getText();
	motoLength = atof(textBoxString);
	if(motoLength < MIN_MOTO_LENGTH || motoLength > MAX_MOTO_LENGTH){
		isAllInputValid = false;
		sprintf(errorMessageTemp, "* %f < moto length < %f\n", MIN_MOTO_LENGTH, MAX_MOTO_LENGTH);
		strcat(errorMessage, errorMessageTemp);
	}


	float carWidth = 0;
	textBoxString = (char*)carWidthInput->editBox->getText();
	carWidth = atof(textBoxString);
	if(carWidth < MIN_CAR_WIDTH || carWidth > MAX_CAR_WIDTH){
		isAllInputValid = false;
		sprintf(errorMessageTemp, "* %f < car width < %f\n", MIN_CAR_WIDTH, MAX_CAR_WIDTH);
		strcat(errorMessage, errorMessageTemp);
	}

	float carLength = 0;
	textBoxString = (char*)carLengthInput->editBox->getText();
	carLength = atof(textBoxString);
	if(carLength < MIN_CAR_LENGTH || carLength > MAX_CAR_LENGTH){
		isAllInputValid = false;
		sprintf(errorMessageTemp, "* %f < car length < %f\n", MIN_CAR_LENGTH, MAX_CAR_LENGTH);
		strcat(errorMessage, errorMessageTemp);
	}

	float busWidth = 0;
	textBoxString = (char*)busWidthInput->editBox->getText();
	busWidth = atof(textBoxString);
	if(busWidth < MIN_BUS_WIDTH || busWidth > MAX_BUS_WIDTH){
		isAllInputValid = false;
		sprintf(errorMessageTemp, "* %f < bus width < %f\n", MIN_BUS_WIDTH, MAX_BUS_WIDTH);
		strcat(errorMessage, errorMessageTemp);
	}

	float busLength = 0;
	textBoxString = (char*)busLengthInput->editBox->getText();
	busLength = atof(textBoxString);
	if(busLength < MIN_BUS_LENGTH || busLength > MAX_BUS_LENGTH){
		isAllInputValid = false;
		sprintf(errorMessageTemp, "* %f < bus length < %f\n", MIN_BUS_LENGTH, MAX_BUS_LENGTH);
		strcat(errorMessage, errorMessageTemp);
	}

	float greenLightTime = 0;
	textBoxString = (char*)greenLightTimeInput->editBox->getText();
	greenLightTime = atoi(textBoxString);
	if(greenLightTime < MIN_GREEN_LIGHT_TIME || greenLightTime > MAX_GREEN_LIGHT_TIME){
		isAllInputValid = false;
		sprintf(errorMessageTemp, "* %f < green light time < %f\n", MIN_GREEN_LIGHT_TIME, MAX_GREEN_LIGHT_TIME);
		strcat(errorMessage, errorMessageTemp);
	}

	float redLightTime = 0;
	textBoxString = (char*)redLightTimeInput->editBox->getText();
	redLightTime = atoi(textBoxString);
	if(redLightTime < MIN_RED_LIGHT_TIME || redLightTime > MAX_RED_LIGHT_TIME){
		isAllInputValid = false;
		sprintf(errorMessageTemp, "* %f < red light time < %f\n", MIN_RED_LIGHT_TIME, MAX_RED_LIGHT_TIME);
		strcat(errorMessage, errorMessageTemp);
	}

	float vBusMax = 0;
	textBoxString = (char*)vMaxBusInput->editBox->getText();
	vBusMax = atof(textBoxString);
	if(vBusMax < MIN_V_MAX_BUS || vBusMax > MAX_V_MAX_BUS){
		isAllInputValid = false;
		sprintf(errorMessageTemp, "* %f < max bus velocity < %f\n", MIN_V_MAX_BUS, MAX_V_MAX_BUS);
		strcat(errorMessage, errorMessageTemp);
	}

	float vCarMax = 0;
	textBoxString = (char*)vMaxCarInput->editBox->getText();
	vCarMax = atof(textBoxString);
	if(vCarMax < MIN_V_MAX_CAR || vCarMax > MAX_V_MAX_CAR){
		isAllInputValid = false;
		sprintf(errorMessageTemp, "* %f < max car velocity < %f\n", MIN_V_MAX_CAR, MAX_V_MAX_CAR);
		strcat(errorMessage, errorMessageTemp);
	}

	float vMotoMax = 0;
	textBoxString = (char*)vMaxMotoInput->editBox->getText();
	vMotoMax = atof(textBoxString);
	if(vMotoMax < MIN_V_MAX_MOTO || vMotoMax > MAX_V_MAX_MOTO){
		isAllInputValid = false;
		sprintf(errorMessageTemp, "* %f < max motor velocity < %f\n", MIN_V_MAX_MOTO, MAX_V_MAX_MOTO);
		strcat(errorMessage, errorMessageTemp);
	}

	if(isAllInputValid){				// valid input
		gameManager->roadLength = roadLength*METTER_TO_POINT;
		CCUserDefault::sharedUserDefault()->setFloatForKey(ROAD_LENGTH_KEY, gameManager->roadLength);

		gameManager->laneWidth = laneWidth*METTER_TO_POINT;
		CCUserDefault::sharedUserDefault()->setFloatForKey(LANE_LENGTH_KEY, gameManager->laneWidth);

		gameManager->motoWidth = motoWidth*METTER_TO_POINT;
		CCUserDefault::sharedUserDefault()->setFloatForKey(MOTO_WIDTH_KEY, gameManager->motoWidth);

		gameManager->motoLength = motoLength*METTER_TO_POINT;
		CCUserDefault::sharedUserDefault()->setFloatForKey(MOTO_LENGTH_KEY, gameManager->motoLength);

		gameManager->carWidth = carWidth*METTER_TO_POINT;
		CCUserDefault::sharedUserDefault()->setFloatForKey(CAR_WIDTH_KEY, gameManager->carWidth);

		gameManager->carLength = carLength*METTER_TO_POINT;
		CCUserDefault::sharedUserDefault()->setFloatForKey(CAR_LENGTH_KEY, gameManager->carLength);

		gameManager->busWidth = busWidth*METTER_TO_POINT;
		CCUserDefault::sharedUserDefault()->setFloatForKey(BUS_WIDTH_KEY, gameManager->busWidth);

		gameManager->busLength = busLength*METTER_TO_POINT;
		CCUserDefault::sharedUserDefault()->setFloatForKey(BUS_LENGTH_KEY, gameManager->busLength);

		gameManager->greenLightTime = greenLightTime;
		CCUserDefault::sharedUserDefault()->setFloatForKey(GREEN_LIGHT_TIME_KEY, gameManager->greenLightTime);

		gameManager->redLightTime = redLightTime;
		CCUserDefault::sharedUserDefault()->setFloatForKey(RED_LIGHT_TIME_KEY, gameManager->redLightTime);

		gameManager->vBusMax = vBusMax*METTER_TO_POINT;
		CCUserDefault::sharedUserDefault()->setFloatForKey(V_MAX_BUS_KEY, gameManager->vBusMax);

		gameManager->vCarMax = vCarMax*METTER_TO_POINT;
		CCUserDefault::sharedUserDefault()->setFloatForKey(V_MAX_CAR_KEY, gameManager->vCarMax);

		gameManager->vMotoMax = vMotoMax*METTER_TO_POINT;
		CCUserDefault::sharedUserDefault()->setFloatForKey(V_MAX_MOTO_KEY, gameManager->vMotoMax);

		gameManager->busLaneMode = busLaneModeSelected;
		CCUserDefault::sharedUserDefault()->setFloatForKey(BUS_LANE_MODE_KEY, busLaneModeSelected);

		CCDirector::sharedDirector()->popScene();
	}
	else{
		CCMessageBox(errorMessage, "Wrong input data");
	}
}

void InputLayer::cancelButtonTouched(CCObject* sender, CCControlEvent event){
	CCDirector::sharedDirector()->popScene();
}